package cn.stylefeng.guns.sys.modular.system.service.impl;

import cn.stylefeng.guns.base.auth.context.LoginContextHolder;
import cn.stylefeng.guns.sys.core.util.DateUtil;
import cn.stylefeng.guns.sys.core.util.ExcelFormatUtil;
import cn.stylefeng.guns.sys.core.util.ExcelUtil;
import cn.stylefeng.guns.sys.modular.system.controller.BaseFrontController;
import cn.stylefeng.guns.sys.modular.system.entity.*;
import cn.stylefeng.guns.sys.modular.system.mapper.MdzxMapper;
import cn.stylefeng.guns.sys.modular.system.mapper.ZxYusuanMapper;
import cn.stylefeng.guns.sys.modular.system.model.params.CwbbParam;
import cn.stylefeng.guns.sys.modular.system.model.result.ZxYusuanResult;
import cn.stylefeng.guns.sys.modular.system.service.ExportService;
import cn.stylefeng.guns.sys.modular.system.service.MdzxService;
import cn.stylefeng.roses.core.util.ToolUtil;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class ExportServiceImpl implements ExportService {
    Logger logger = LoggerFactory.getLogger(ExportServiceImpl.class);

    @Resource
    private ZxYusuanMapper zxYusuanMapper;
    @Resource
    private MdzxMapper mdzxMapper;
    @Resource
    private MdzxService mdzxService;

    @Override
    public ResponseEntity<byte[]> exportExcel(HttpServletRequest request, HttpServletResponse response, Long btyZxMdzxId) {
        try {
            logger.info(">>>>>>>>>>开始导出excel>>>>>>>>>>");
            //门店
            Mdzx mdzx = mdzxMapper.selectById(btyZxMdzxId);
            //TODO-1 要导出的数据内容
            List<ZxYusuanResult> list = zxYusuanMapper.selectListByBtyZxMdzxId(btyZxMdzxId);
            BaseFrontController baseFrontController = new BaseFrontController();
            //文件名称
            String shopName = mdzx.getBtyBrandIdView();
            return baseFrontController.buildResponseEntity(export(list, shopName), shopName + ".xls");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(">>>>>>>>>>导出excel 异常，原因为：" + e.getMessage());
        }
        return null;
    }

    @Override
    public ResponseEntity<byte[]> exportExcels(HttpServletRequest request, HttpServletResponse response, String[] btyZxMdzxIds) {
        try {
            logger.info(">>>>>>>>>>开始导出excel>>>>>>>>>>");
            //门店

            List<List<ZxYusuanResult>> lists = new ArrayList<>();
            List<String> shopNames=new ArrayList<>();

            for (int i = 0; i < btyZxMdzxIds.length; i++) {
                Mdzx mdzx = mdzxMapper.selectById(btyZxMdzxIds[i]);
                //TODO-1 要导出的数据内容
                List<ZxYusuanResult> list = zxYusuanMapper.selectListByBtyZxMdzxId(Long.valueOf(btyZxMdzxIds[i]));

                //文件名称
                String shopName = mdzx.getBtyBrandIdView();

                lists.add(list);
                shopNames.add(shopName);
            }

            BaseFrontController baseFrontController = new BaseFrontController();
            return baseFrontController.buildResponseEntity(exportFirst(lists, shopNames),  "装修预算.xls");


        } catch (Exception e) {
            e.printStackTrace();
            logger.error(">>>>>>>>>>导出excel 异常，原因为：" + e.getMessage());
        }
        return null;
    }


    private InputStream exportFirst(List<List<ZxYusuanResult>> lists, List<String> shopNames) {


        logger.info(">>>>>>>>>>>>>>>>>>>>开始进入导出方法>>>>>>>>>>");
        ByteArrayOutputStream output = null;
        InputStream inputStream1 = null;
        SXSSFWorkbook wb = new SXSSFWorkbook(1000);// 保留1000条数据在内存中


        for (int index = 0; index < lists.size(); index++) {
            List<ZxYusuanResult> list = lists.get(index);
            String shopName = shopNames.get(index);


            SXSSFSheet sheet = wb.createSheet(shopName);

            // 设置报表头样式
            CellStyle header = ExcelFormatUtil.headSytle(wb);// cell样式
            CellStyle content = ExcelFormatUtil.contentStyle(wb);// 报表体样式

            //TODO-2 每一列字段名
            String[] titles = new String[]{"序号", "项目名称", "金额"};

            // 字段名所在表格的宽度
            int[] ints = new int[]{5000, 5000, 5000, 5000, 5000, 5000};

            //TODO-3 设置总标题内容，没有可略过
            //设置第一行标题：指定 4 个参数，起始行，结束行，起始列，结束列,
            int firstRow = 1;
            int lastRow = 1;
            int firstCol = 1;
            int lastCol = 3;
            SXSSFRow row1 = sheet.createRow(0);
            SXSSFCell cell0 = row1.createCell(0);
            CellRangeAddress regionFist = new CellRangeAddress(firstRow - 1, lastRow - 1, firstCol - 1, lastCol - 1);
            sheet.addMergedRegion(regionFist);
            //设置每一列的字段名

            int contentStartRow = 4;
            //获取总面积
            String  mianji = "";
            if (list != null && list.size() > 0) {
                    mianji=list.get(0).getMianji();
            }

            cell0.setCellValue("投资预算表("+mianji+"平)");
            cell0.setCellStyle(header);
            //设置第二行标题
            SXSSFRow secondRow = sheet.createRow(1);
            //设置第二行标题的内容
            SXSSFCell cell1 = secondRow.createCell(0);
            //设置每一列的字段名
            cell1.setCellValue("单店:");
            cell1.setCellStyle(header);

            SXSSFCell cell2 = secondRow.createCell(1);
            //设置每一列的字段名
            cell2.setCellValue(shopName);
            cell2.setCellStyle(header);

            SXSSFCell cell3 = secondRow.createCell(2);
            //设置每一列的字段名
            cell3.setCellValue("单位：元");
            cell3.setCellStyle(header);

            //TODO-4 设置内容标题
            //内容的标题所在行
            int concentitleStartRow = 3;
            //设置表头样式
            ExcelFormatUtil.initContentTitleEX(sheet, header, concentitleStartRow, titles, ints);
            logger.info(">>>>>>>>>>>>>>>>>>>>表头样式设置完成>>>>>>>>>>");

            //TODO-5 从第4行开始为内容数据
            //int contentStartRow = 4;
            //总计计算
            BigDecimal sum = BigDecimal.ZERO;
            //预计投资
            BigDecimal yjtz = BigDecimal.ZERO;

            if (list != null && list.size() > 0) {
                logger.info(">>>>>>>>>>>>>>>>>>>>开始遍历数据组装单元格内容>>>>>>>>>>");
                for (int i = 0; i < list.size(); i++) {
                    ZxYusuanResult result = list.get(i);

                    SXSSFRow row = sheet.createRow(contentStartRow + i - 1);
                    int j = 0;

                    // 序号
                    SXSSFCell cell = row.createCell(j++);
                    cell.setCellValue(result.getXuhao());
                    cell.setCellStyle(content);

                    // 项目名称
                    cell = row.createCell(j++);
                    if(ToolUtil.isNotEmpty(result.getSjdw())){
                        cell.setCellValue(result.getXiangmu()+"("+result.getSjdw()+")");
                    }else{
                        cell.setCellValue(result.getXiangmu());
                    }
                    cell.setCellStyle(content);

                    // 金额
                    cell = row.createCell(j++);
                    cell.setCellValue(result.getJine() == null ? "0" : result.getJine().toString());
                    cell.setCellStyle(content);

                    //金额总计计算
                    sum = sum.add(result.getJine() == null ? BigDecimal.ZERO : result.getJine());
                    mianji=list.get(0).getMianji();
                    yjtz=list.get(0).getYjtz()==null?BigDecimal.ZERO:list.get(0).getYjtz();
                }
                logger.info(">>>>>>>>>>>>>>>>>>>>结束遍历数据组装单元格内容>>>>>>>>>>");
            }

            //TODO-设置总计预估值
            //所在行
            int sumRowNum = contentStartRow + list.size();
            SXSSFRow rowSum = sheet.createRow(sumRowNum - 1);
            SXSSFCell cellSum = rowSum.createCell(0);
            cellSum.setCellValue("总计");
            cellSum.setCellStyle(content);
            SXSSFCell cellSum1 = rowSum.createCell(1);
            //空单元格
            cellSum1.setCellValue(sum.toString());
            cellSum1.setCellStyle(content);
            //合并
            CellRangeAddress sumRegion = new CellRangeAddress(sumRowNum - 1, sumRowNum - 1, 0, 1);
            sheet.addMergedRegion(sumRegion);

            SXSSFCell cellSum2 = rowSum.createCell(2);
            //预估值
            cellSum2.setCellValue(sum.toString());
            cellSum2.setCellStyle(content);

//            SXSSFCell cellSum3 = rowSum.createCell(3);
//            cellSum3.setCellValue("总面积(平米)");
//            cellSum3.setCellStyle(content);
//
//            SXSSFCell cellSum4 = rowSum.createCell(4);
//            //预估值
//            cellSum4.setCellValue(mianji);
//            cellSum4.setCellStyle(content);
//
//            SXSSFCell cellSum5 = rowSum.createCell(5);
//            cellSum5.setCellValue("预计投资");
//            cellSum5.setCellStyle(content);

            SXSSFCell cellSum6 = rowSum.createCell(3);
            //预估值
            cellSum6.setCellValue(yjtz.toString());
            cellSum6.setCellStyle(content);

            //TODO 制表人、时间
            //所在行
            int endRow = sumRowNum + 1;
            SXSSFRow rowEnd = sheet.createRow(endRow - 1);
            //制表人
            SXSSFCell cellEnd0 = rowEnd.createCell(0);
            cellEnd0.setCellValue("制表人：" + LoginContextHolder.getContext().getUser().getName());
            //制表时间
            SXSSFCell cellEnd1 = rowEnd.createCell(titles.length - 1);
            cellEnd1.setCellValue(DateUtil.getNow());
        }

        try {
            output = new ByteArrayOutputStream();
            wb.write(output);
            inputStream1 = new ByteArrayInputStream(output.toByteArray());
            output.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            try {
                if (output != null) {
                    output.close();
                    if (inputStream1 != null) {
                        inputStream1.close();
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return inputStream1;

    }


    private InputStream export(List<ZxYusuanResult> list, String shopName) {
        logger.info(">>>>>>>>>>>>>>>>>>>>开始进入导出方法>>>>>>>>>>");
        ByteArrayOutputStream output = null;
        InputStream inputStream1 = null;
        SXSSFWorkbook wb = new SXSSFWorkbook(1000);// 保留1000条数据在内存中
        SXSSFSheet sheet = wb.createSheet();
        SXSSFSheet sheet2 = wb.createSheet();
        // 设置报表头样式
        CellStyle header = ExcelFormatUtil.headSytle(wb);// cell样式
        CellStyle content = ExcelFormatUtil.contentStyle(wb);// 报表体样式

        //TODO-2 每一列字段名
        String[] titles = new String[]{"序号", "项目名称", "金额"};

        // 字段名所在表格的宽度
        int[] ints = new int[]{5000, 5000, 5000, 5000, 5000, 5000};

        //TODO-3 设置总标题内容，没有可略过
        //设置第一行标题：指定 4 个参数，起始行，结束行，起始列，结束列,
        int firstRow = 1;
        int lastRow = 1;
        int firstCol = 1;
        int lastCol = 3;
        SXSSFRow row1 = sheet.createRow(0);
        SXSSFCell cell0 = row1.createCell(0);
        CellRangeAddress regionFist = new CellRangeAddress(firstRow - 1, lastRow - 1, firstCol - 1, lastCol - 1);
        sheet.addMergedRegion(regionFist);
        //设置每一列的字段名
        cell0.setCellValue("投资预算表");
        cell0.setCellStyle(header);
        //设置第二行标题
        SXSSFRow secondRow = sheet.createRow(1);
        //设置第二行标题的内容
        SXSSFCell cell1 = secondRow.createCell(0);
        //设置每一列的字段名
        cell1.setCellValue("单店:");
        cell1.setCellStyle(header);

        SXSSFCell cell2 = secondRow.createCell(1);
        //设置每一列的字段名
        cell2.setCellValue(shopName);
        cell2.setCellStyle(header);

        SXSSFCell cell3 = secondRow.createCell(2);
        //设置每一列的字段名
        cell3.setCellValue("单位：元");
        cell3.setCellStyle(header);

        //TODO-4 设置内容标题
        //内容的标题所在行
        int concentitleStartRow = 3;
        //设置表头样式
        ExcelFormatUtil.initContentTitleEX(sheet, header, concentitleStartRow, titles, ints);
        logger.info(">>>>>>>>>>>>>>>>>>>>表头样式设置完成>>>>>>>>>>");

        //TODO-5 从第4行开始为内容数据
        int contentStartRow = 4;
        //总计计算
        BigDecimal sum = BigDecimal.ZERO;

        if (list != null && list.size() > 0) {
            logger.info(">>>>>>>>>>>>>>>>>>>>开始遍历数据组装单元格内容>>>>>>>>>>");
            for (int i = 0; i < list.size(); i++) {
                ZxYusuanResult result = list.get(i);

                SXSSFRow row = sheet.createRow(contentStartRow + i - 1);
                int j = 0;

                // 序号
                SXSSFCell cell = row.createCell(j++);
                cell.setCellValue(result.getXuhao());
                cell.setCellStyle(content);

                // 项目名称
                cell = row.createCell(j++);
                cell.setCellValue(result.getXiangmu());
                cell.setCellStyle(content);

                // 金额
                cell = row.createCell(j++);
                cell.setCellValue(result.getJine() == null ? "0" : result.getJine().toString());
                cell.setCellStyle(content);

                //金额总计计算
                sum = sum.add(result.getJine() == null ? BigDecimal.ZERO : result.getJine());

            }
            logger.info(">>>>>>>>>>>>>>>>>>>>结束遍历数据组装单元格内容>>>>>>>>>>");
        }

        //TODO-设置总计预估值
        //所在行
        int sumRowNum = contentStartRow + list.size();
        SXSSFRow rowSum = sheet.createRow(sumRowNum - 1);
        SXSSFCell cellSum = rowSum.createCell(0);
        cellSum.setCellValue("总计");
        cellSum.setCellStyle(content);
        SXSSFCell cellSum1 = rowSum.createCell(1);
        //空单元格
        cellSum1.setCellValue(sum.toString());
        cellSum1.setCellStyle(content);
        //合并
        CellRangeAddress sumRegion = new CellRangeAddress(sumRowNum - 1, sumRowNum - 1, 0, 1);
        sheet.addMergedRegion(sumRegion);

        SXSSFCell cellSum2 = rowSum.createCell(2);
        //预估值
        cellSum2.setCellValue(sum.toString());
        cellSum2.setCellStyle(content);

        //TODO 制表人、时间
        //所在行
        int endRow = sumRowNum + 1;
        SXSSFRow rowEnd = sheet.createRow(endRow - 1);
        //制表人
        SXSSFCell cellEnd0 = rowEnd.createCell(0);
        cellEnd0.setCellValue("制表人：" + LoginContextHolder.getContext().getUser().getName());
        //制表时间
        SXSSFCell cellEnd1 = rowEnd.createCell(titles.length - 1);
        cellEnd1.setCellValue(DateUtil.getNow());

        try {
            output = new ByteArrayOutputStream();
            wb.write(output);
            inputStream1 = new ByteArrayInputStream(output.toByteArray());
            output.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            try {
                if (output != null) {
                    output.close();
                    if (inputStream1 != null) {
                        inputStream1.close();
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return inputStream1;
    }

}
